package com.controller.sys.sysMenu;
import com.common.emums.DataStatus;
import com.core.springSecurity.service.PermissionService;
import com.github.pagehelper.PageInfo;
import com.common.utils.DateUtils;
import com.model.base.PageResult;
import com.common.utils.StringUtils;
import com.common.exception.BusinessException;
import com.common.ErrorCodeEnum;
import com.common.anntation.Log;
import com.common.emums.BusinessType;
import com.common.utils.Utils;
import com.common.utils.EntityConversionUtil;
import com.model.base.Result;
import com.model.dto.sys.menu.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import org.springframework.beans.BeanUtils;
import org.springframework.web.multipart.MultipartFile;
import javax.validation.Valid;
import javax.servlet.http.HttpServletResponse;
import com.model.vo.sys.menu.*;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

import com.common.excel.ExcelUtil;
import com.model.pojo.sys.SysMenu;
import com.service.sys.SysMenuService;

/**
 * @Author: zql
 * @Description: 菜单权限模块
 * @Data: 2021-07-09
 */
@Api(tags = {"菜单权限"})
@Slf4j
@RestController
@RequestMapping("/v1")
public class SysMenuController {
    @Resource
    SysMenuService sysMenuService;

    /**
     * @Author: zql
     * @Description: 创建菜单权限
     * @param createSysMenuDTO 请求数据
     * @Data: 2021-07-09
     */
    @Log(title = "创建菜单权限", businessType = BusinessType.INSERT)
    @ApiOperation(value = "创建菜单权限")
    @PostMapping("/createSysMenu")
    @PreAuthorize("@ss.hasAnyPermi('" + PermissionService.SYSTEM_OPERATE + "')")
    public Result<Objects> createSysMenu(@RequestBody @Valid CreateSysMenuDTO createSysMenuDTO) {
        SysMenu sysMenu = new SysMenu();
        BeanUtils.copyProperties(createSysMenuDTO, sysMenu);
        sysMenuService.create(sysMenu);
        return Result.suc();
    }

    /**
     * @Author: zql
     * @Description: 修改菜单权限
     * @param updateSysMenuDTO 请求数据
     * @Data: 2021-07-09
     */
    @Log(title = "修改菜单权限", businessType = BusinessType.UPDATE)
    @ApiOperation(value = "修改菜单权限")
    @PostMapping("/updateSysMenu")
    @PreAuthorize("@ss.hasAnyPermi('" + PermissionService.SYSTEM_OPERATE + "')")
    public Result<Objects> updateSysMenu(@RequestBody @Valid UpdateSysMenuDTO updateSysMenuDTO) {
        SysMenu sysMenu = EntityConversionUtil.copy(updateSysMenuDTO, SysMenu.class);
        sysMenuService.update(sysMenu);
        return Result.suc();
    }

    /**
     * @Author: zql
     * @Description: 批量修改菜单权限
     * @param updateSysMenuListDTO 请求数据
     * @Data: 2021-07-09
     */
    @Log(title = "批量修改菜单权限", businessType = BusinessType.UPDATE)
    @ApiOperation(value = "批量修改菜单权限")
    @PostMapping("/updateSysMenuList")
    @PreAuthorize("@ss.hasAnyPermi('" + PermissionService.SYSTEM_OPERATE + "')")
    public Result<Objects> updateSysMenu(@RequestBody @Valid UpdateSysMenuListDTO updateSysMenuListDTO) {
        List<SysMenu> sysMenuList = new ArrayList<>();
        updateSysMenuListDTO.getSysMenuSet().forEach(sysMenuInfo -> {
            if (StringUtils.isNull(sysMenuInfo.getSysMenuId())) {
                throw new BusinessException(ErrorCodeEnum.PARAM_FAILED.setParam("菜单id不存在"));
            }
            SysMenu sysMenu = sysMenuService.get(sysMenuInfo.getSysMenuId());
            if (StringUtils.isNull(sysMenu)) {
                throw new BusinessException(ErrorCodeEnum.ERROR_MESSAGE.setParam("菜单不存在,菜单id:"+sysMenuInfo.getSysMenuId()));
            }
            BeanUtils.copyProperties(sysMenuInfo, sysMenu);
            sysMenuService.verifyInfo(sysMenu, true);
            sysMenuList.add(sysMenu);
        });
        if (sysMenuList.size() > 0) {
            sysMenuService.updateList(sysMenuList);
        }
        return Result.suc();
    }

    /**
    * @Author: zql
    * @Description: 查看菜单权限列表
     * @param getSysMenuListDTO 请求数据
     * @Data: 2021-07-09
     */
    @ApiOperation(value = "查看菜单权限列表")
    @PostMapping("/getSysMenuList")
    @PreAuthorize("@ss.hasAnyPermi('" + PermissionService.SYSTEM_OPERATE + "')")
    public Result<PageResult<List<GetSysMenuVO>>> getSysMenuList(@RequestBody @Valid GetSysMenuListDTO getSysMenuListDTO) {
        List<SysMenu> sysMenuList = sysMenuService.getList(getSysMenuListDTO);
        PageInfo<SysMenu> pageInfo = new PageInfo<>(sysMenuList);
        List<GetSysMenuVO> getSysMenuVOList = EntityConversionUtil.copyList(sysMenuList, GetSysMenuVO.class);
        PageResult<List<GetSysMenuVO>> build = PageResult.<List<GetSysMenuVO>>builder().result(getSysMenuVOList).pageInfo(pageInfo).build();
        return Result.suc(build);
    }

    /**
     * @Author: zql
     * @Description: 查看菜单权限列表
     * @param updateSysMenuStatusDTO 请求数据
     * @Data: 2021-07-09
     */
    @ApiOperation(value = "修改菜单权限状态")
    @Log(title = "修改菜单权限状态", businessType = BusinessType.UPDATE)
    @PostMapping("/updateSysMenuStatus")
    @PreAuthorize("@ss.hasAnyPermi('" + PermissionService.SYSTEM_OPERATE + "')")
    public Result<Objects> updateSysMenuStatus(@RequestBody @Valid UpdateSysMenuStatusDTO updateSysMenuStatusDTO) {
        SysMenu sysMenuDB = sysMenuService.get(updateSysMenuStatusDTO.getSysMenuId(),null);
        if(DataStatus.OK.equals(updateSysMenuStatusDTO.getIsDelete()) && !DataStatus.OK.equals(sysMenuDB.getIsDelete())){
            log.debug("数据从停用/删除状态改成正常状态,需要做唯一性校验从这执行");
        }

        SysMenu sysMenu = new SysMenu();
        sysMenu.setSysMenuId(updateSysMenuStatusDTO.getSysMenuId());
        sysMenu.setIsDelete(updateSysMenuStatusDTO.getIsDelete());
        sysMenuService.update(sysMenu);
        return Result.suc();
    }

   /**
     * @Author: zql
     * @Description: 导入菜单权限表
     * @param excel 导入的excel内容
     * @Data: 2021-07-09
     */
    @Log(title = "导入菜单权限表", businessType = BusinessType.IMPORT)
    @ApiOperation(value = "导入菜单权限表")
    @PostMapping(value = "/importSysMenu")
    @PreAuthorize("@ss.hasAnyPermi('" + PermissionService.SYSTEM_OPERATE + "')")
    public Result<ImportSysMenuVO> importSysMenu(@RequestParam("file") MultipartFile excel){
        if (StringUtils.isNull(excel)){
            throw new BusinessException(ErrorCodeEnum.EXCEL_NOT_FOUNT);
        }
        List<SysMenuExcel> sysMenuExcelList = ExcelUtil.readExcel(excel, 1, 1, SysMenuExcel.class);
        if (StringUtils.isNull(sysMenuExcelList) || sysMenuExcelList.size() <= 0) {
            throw new BusinessException(ErrorCodeEnum.EXCEL_NOT_FOUNT);
        }

        List<ErrorSysMenuVO> errorSysMenuVOList = new ArrayList<>();
        List<SysMenu> sysMenuList = new ArrayList<>();
        for (SysMenuExcel sysMenuExcel : sysMenuExcelList) {
            String name= Utils.verifyNullMember(sysMenuExcel,"sysMenuId");
            if(!"".equals(name)) {
                errorSysMenuVOList.add(EntityConversionUtil.copy(sysMenuExcel, ErrorSysMenuVO.class).errMsg("字段" + name + "为空"));
                log.error("字段{}为空", name);
                continue;
            }
            SysMenu sysMenu = new SysMenu();
            BeanUtils.copyProperties(sysMenuExcel, sysMenu);
            if (StringUtils.isNotNull(sysMenuExcel.getIsFrame())) {
                sysMenu.setIsFrame(sysMenuExcel.getIsFrame().byteValue());
            }
            if (StringUtils.isNotNull(sysMenuExcel.getIsCache())) {
                sysMenu.setIsCache(sysMenuExcel.getIsCache().byteValue());
            }
            if (StringUtils.isNotNull(sysMenuExcel.getMenuType())) {
                sysMenu.setMenuType(sysMenuExcel.getMenuType().byteValue());
            }
            if (StringUtils.isNotNull(sysMenuExcel.getVisible())) {
                sysMenu.setVisible(sysMenuExcel.getVisible().byteValue());
            }
            try {
               sysMenuService.verifyInfo(sysMenu, StringUtils.isNotNull(sysMenu.getSysMenuId()));
            } catch (BusinessException e) {
                errorSysMenuVOList.add(EntityConversionUtil.copy(sysMenu, ErrorSysMenuVO.class).errMsg(e.getErrorCodeEnum().getErrorMsg()));
                log.error("{}", e.getErrorCodeEnum().getErrorMsg());
                continue;
            }
            sysMenuList.add(sysMenu);
        }
        sysMenuList.forEach(sysMenu -> sysMenuService.verifyInfo(sysMenu, StringUtils.isNotNull(sysMenu.getSysMenuId())));
        if (sysMenuList.size()>0){
            sysMenuService.updateAndInsert(sysMenuList);
        }

    return Result.suc(ImportSysMenuVO.builder().importSuccess(sysMenuList.size()).errorSysMenuVOList(errorSysMenuVOList).build());
    }

   /**
     * @Author: zql
     * @Description: 导出菜单权限表
     * @param getSysMenuListDTO 请求数据
     * @param response 返回内容
     * @Data: 2021-07-09
     */
    @Log(title = "导出菜单权限表", businessType = BusinessType.EXPORT,isSaveResponseData = false)
    @ApiOperation(value = "导出菜单权限表")
    @PostMapping(value = "/exportSysMenu")
    @PreAuthorize("@ss.hasAnyPermi('" + PermissionService.SYSTEM_OPERATE + "')")
    public Result<Objects> exportSysMenu(@RequestBody @Valid GetSysMenuListDTO getSysMenuListDTO, HttpServletResponse response) throws BusinessException {
        List<SysMenu> sysMenuList = sysMenuService.getList(getSysMenuListDTO);
        List<SysMenuExcel> sysMenuExcelList = new ArrayList<>();
        for (SysMenu sysMenu : sysMenuList) {
            SysMenuExcel sysMenuExcel = new SysMenuExcel();
            BeanUtils.copyProperties(sysMenu, sysMenuExcel);
            sysMenuExcel.setIsFrame(sysMenu.getIsFrame().intValue());
            sysMenuExcel.setIsCache(sysMenu.getIsCache().intValue());
            sysMenuExcel.setMenuType(sysMenu.getMenuType().intValue());
            sysMenuExcel.setVisible(sysMenu.getVisible().intValue());
            sysMenuExcelList.add(sysMenuExcel);
        }
        String fileName = "菜单权限信息表" + DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, new Date());
        try {
            ExcelUtil.writeExcel(response, sysMenuExcelList, fileName, "菜单权限信息", new SysMenuExcel());
        } catch (IOException e) {
            log.error("导出失败，文件名:{}", fileName);
        }
        return Result.suc();
    }
}